home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1993 July / InfoMagic USENET CD-ROM July 1993.ISO / sources / misc / volume6 / glib / part06 < prev    next >
Encoding:
Text File  |  1989-05-14  |  50.5 KB  |  1,976 lines

  1. Newsgroups: comp.sources.misc
  2. From: allbery@uunet.UU.NET (Brandon S. Allbery - comp.sources.misc)
  3. Subject: v06i107: glib part 6 of 15
  4. Reply-To: lee@uhccux.uhcc.Hawaii.Edu (Greg Lee )
  5.  
  6. Posting-number: Volume 6, Issue 107
  7. Submitted-by: lee@uhccux.uhcc.Hawaii.Edu (Greg Lee )
  8. Archive-name: glib/part06
  9.  
  10. #! /bin/sh
  11. # This is a shell archive.  Remove anything before this line, then unpack
  12. # it by saving it into a file and typing "sh file".  To overwrite existing
  13. # files, type "sh file -c".  You can also feed this as standard input via
  14. # unshar, or by typing "sh <file", e.g..  If this archive is complete, you
  15. # will see the following message at the end:
  16. #        "End of archive 6 (of 15)."
  17. # Contents:  PORTING k1multi.mnu pc-ints.asm pc-mach.c
  18. # Wrapped by lee@uhccux on Sun May  7 00:40:13 1989
  19. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  20. if test -f 'PORTING' -a "${1}" != "-c" ; then 
  21.   echo shar: Will not clobber existing file \"'PORTING'\"
  22. else
  23. echo shar: Extracting \"'PORTING'\" \(12157 characters\)
  24. sed "s/^X//" >'PORTING' <<'END_OF_FILE'
  25. X$Id: PORTING,v 1.6 89/05/06 17:13:07 lee Exp $
  26. X[Lee:]
  27. X
  28. XThe C source code for the various synth modules is generated by
  29. Xa program 'menutoc'.  Although C source for 'menutoc' is included,
  30. Xrevising the program would require flex, the freely distributed "fast
  31. Xlex" to compile.  But if you happen not to have flex, lex will serve --
  32. Xsee the note in the Makefile and notes at the beginning of file
  33. Xmakemenu.l.
  34. X
  35. X    ---------------------------------
  36. X[Kesti:]
  37. X
  38. XIn order to adapt it to the D-10's rather large data set, I have used glib's
  39. Xability to service multiple synths to instead service sub-sections of a single
  40. XD-10.  These subsections are:
  41. X
  42. X    Performance mode patches
  43. X    Multi-timbral mode timbres
  44. X
  45. X    Tone waveform generators
  46. X    Tone time variant filters
  47. X    Tone time variant amplifiers
  48. X
  49. X    Rhythm setup
  50. X    Rhythm patterns
  51. X    Rhythm track
  52. X
  53. XBecause the memory requirement of a single program to service this much data
  54. Xis large enough to be cumbersome, I have broken the subsections into three
  55. Xseparate programs.  These are d10patch, d10tone, and d10drum.
  56. X
  57. XThe tone services also require a separate program because, unlike all other
  58. Xservices, they must operate on a single common data set.  This required
  59. Xchanges to the data memory allocation and other functions in glib.c.  When
  60. Xcompiling d10tone, be sure to #define SINGLEDATA in glib.c to enable these
  61. Xchanges.
  62. X
  63. XI believe that I have maintained glib's ability to be compiled for Un*x
  64. X(using SysV curses), DOS, and the Atari ST.  The sources supplied have
  65. Xbeen succesfully compiled and run on an AT&T 3b1, running v3.51 software;
  66. Xand an AT&T 6300 (with a V30 in the cpu socket), running AT&T's version of
  67. XDOS v3.20.  Borland Turbo C v1.0 was used to produce the executables and the
  68. Xmachine was fitted with a CMS-401 interface.
  69. X
  70. XThe Makefile provided was used on the 3b1, and produces a single executable
  71. Xnamed glib that combines all services, but does not tie the tone data
  72. Xtogether as discussed above.  This is presumably no problem, as the Un*x
  73. Xversion is intended to be for demo purposes.  If your Un*x machine has a
  74. Xmidi interface, I'd like hear from you!
  75. X
  76. XThe Turbo C project files (*.prj) are used by the integrated environment to
  77. Xproduce glib.exe, d10patch.exe, d10tone.exe, and d10drum.exe.  Be sure to
  78. Xuse the large memory model.  It is not recommended that glib.exe be used, as
  79. Xit requires almost all the available memory of a 640K machine, and again,
  80. Xwould not tie the tone data together (SINGLEDATA should not be #defined
  81. Xwhen compiling for glib.exe.).
  82. X
  83. X[Lee:]
  84. X
  85. XI did not include the .prj files mentioned above.  So many files
  86. Xalready!  But below are the contents of those files.  The file machdep.c
  87. Xis a copy of pc-mach.c (and pc-mach.h should be copied to machdep.h);
  88. Xthe d10*.c files except d10ton.c) must be constructed from the
  89. Xcorresponding d10*.mnu files by the menutoc program; and the files
  90. Xlistdrum.c, listpat.c, and listton.c are the same as file list.c, but
  91. Xwith '#defines' removed for the unused modules.  That is to say, for the
  92. XD10 '#defines', keep only
  93. X    #define D10urp
  94. X    #define D10rsu
  95. X    #define D10tra
  96. Xfor listdrum.c, keep only
  97. X    #define D10pat
  98. X    #define D10tim
  99. Xfor listpat.c, and keep only
  100. X    #define D10wfg
  101. X    #define D10tvf
  102. X    #define D10tva
  103. Xfor listton.c.
  104. X::::::::::::::
  105. Xcontents of file d10drum.prj
  106. X::::::::::::::
  107. Xd10urp.c
  108. Xd10rsu.c
  109. Xd10tra.c
  110. Xglib.c
  111. Xlistdrum.c
  112. Xvis.c
  113. Xmachdep.c
  114. X::::::::::::::
  115. Xcontents of file d10patch.prj
  116. X::::::::::::::
  117. Xd10pat.c
  118. Xd10tim.c
  119. Xglib.c
  120. Xlistpat.c
  121. Xvis.c
  122. Xmachdep.c
  123. X::::::::::::::
  124. Xcontents of file d10tone.prj
  125. X::::::::::::::
  126. Xd10ton.c
  127. Xd10wfg.c
  128. Xd10tvf.c
  129. Xd10tva.c
  130. Xglib.c
  131. Xlisttone.c
  132. Xvis.c
  133. Xmachdep.c
  134. X::::::::::::::
  135. Xcontents of file glib.prj
  136. X::::::::::::::
  137. Xd10pat.c
  138. Xd10tim.c
  139. Xd10wfg.c
  140. Xd10ton.c
  141. Xd10tvf.c
  142. Xd10tva.c
  143. Xd10urp.c
  144. Xd10rsu.c
  145. Xd10tra.c
  146. Xglib.c
  147. Xlist.c
  148. Xvis.c
  149. Xmachdep.c
  150. X----------------------
  151. X
  152. X
  153. X[Thompson:]
  154. X
  155. XCompiling
  156. X---------
  157. Xmachdep.c and machdep.h are machine-dependent parts.  The *-mach.h and
  158. X*-mach.c files are the versions of these files for different machines,
  159. Xe.g. unix-mach.[ch] is for UNIX, st-mach.[ch] is for the Atari ST.
  160. XCopy the proper files to machdep.c and machdep.h before compiling
  161. Xfor a particular machine.   For example, on UNIX, do the following:
  162. X
  163. X    cp unix-mach.c machdep.c
  164. X    cp unix-mach.h machdep.h
  165. X    make glib
  166. X
  167. XThe contents of list.c control which synths are supported; modify
  168. Xthe defines at the beginning of that file appropriately.  When
  169. Xcompiling, you need to include glib.c and the appropriate synth
  170. Xfiles (e.g. if you define DW8000 in list.c, then you need to compile
  171. Xwith dw8000.c).  A single version of glib can support as many synths
  172. Xas you want, although some compilers may have size limitations or
  173. Xoverlay schemes that get in the way.
  174. X
  175. X
  176. XHacking glib - Internals
  177. X------------------------
  178. XThe program is written so that support for a new synth can be added by
  179. Xadding an entry to the array in list.c, describing the various attributes
  180. Xof the synthesizer and the C functions to be called to control it.  And, of
  181. Xcourse, you have to write those C functions.  Adding a new synth, for a
  182. Xreasonable C programmer, might be described as mostly straightforward but
  183. Xtedious.  People other than the original author HAVE done it, with no help.
  184. XGlib allows you to re-use the front-end interface of the librarian and
  185. Xeditor, but it does not relieve you of having to write C code which
  186. Xinteracts with the synth (which, depending on the synth, can of course be
  187. Xeasy or maddening) and with the raw data formats.  Naturally, using one of
  188. Xthe existing synth files as an example of how to do things is the best way
  189. Xto start on a new one.
  190. X
  191. XThe 'E' array in list.c has the following structure:
  192. X
  193. Xstruct editinfo {
  194. X    char *ed_name;        /* Synth name */
  195. X    struct paraminfo *ed_params;    /* list of parameters */
  196. X    struct labelinfo *ed_labels;    /* screen labels in edit mode */
  197. X    int ed_nvoices;        /* number of voices */
  198. X    int ed_vsize;        /* size of each voice data, in bytes */
  199. X    int ed_nsize;        /* name size */
  200. X    int ed_dataid;        /* data ID */
  201. X    int (*ed_din)();    /* copy voice data into paraminfo array */
  202. X    int (*ed_dout)();    /* copy voice data out of paraminfo array */
  203. X    int (*ed_sedit)();    /* send 1 voice to synth edit buffer */
  204. X    int (*ed_sone)();    /* send 1 voice to a synth (permanent) patch*/
  205. X    int (*ed_sbulk)();    /* send bulk voice data */
  206. X    int (*ed_gbulk)();    /* get bulk voice data */
  207. X    char *(*ed_nof)();    /* get name of a voice out of data */
  208. X    int (*ed_snof)();    /* set name of a voice in data */
  209. X    char *(*ed_numof)();    /* convert voice number to on-screen text */
  210. X    int (*ed_cvtnum)();    /* convert visable voice number to std. format */
  211. X};
  212. X
  213. XIn glib, there are several relatively independent representations of the
  214. Xsynth voice data.  First, there is the data that is stored in the
  215. Xlibrary and synth banks (ie.  the data used and manipulated via the
  216. Xlibrarian screen).  This is the format of the data that is written to
  217. Xand read from files (a single byte, given as 'ed_dataid' above, is added
  218. Xto the beginning of the file, to identify it).  The size of a single
  219. Xvoice in this data is 'ed_vsize'.  The number of voices in a bank is
  220. X'ed_nvoices', so the amount of space taken up by a library bank is
  221. Xed_vsize * ed_nvoices.
  222. X
  223. XWhen a voice is edited, the voice data is copied into the parameter
  224. Xarray (see below), in p_val.  The 'ed_din' function is called to do this.
  225. XAfter a voice is edited, 'ed_dout' takes the updated parameter values 
  226. Xand puts them back into the original data format.  Note that this means
  227. Xthat the bytes in the 'raw' voice data and the values in the parameter
  228. Xarray (ie. the values manipulated by the editor) need not be the same.
  229. XThere are utility functions 'getval' and 'setval' which should be used
  230. Xfor getting and setting the values in the parameter array.  See dx100.c
  231. Xfor usage.
  232. X
  233. XThe ed_sedit, ed_sone, ed_sbulk, and ed_gbulk functions are called to
  234. Xsend voices to and get voices from the synthesizer.  Only one of ed_sone
  235. Xand ed_sbulk need be defined, although ed_sone should be preferred.
  236. X(I had trouble getting the DX100 to accept a single permanent voice
  237. Xchange, so it always does a bulk voice transfer.)  The data passed to
  238. Xthese functions is in the library bank format.  The ed_gbulk function is
  239. Xoptional, so that write-only MIDI devices (like the DEP-5) are allowed.
  240. X
  241. XThe ed_nof function is called to pull the voice name out of the raw
  242. Xvoice data (as stored in the library banks), and it should return a
  243. XC string containing the name.  The ed_snof function is called to
  244. Xstick a voice name into the raw voice data.  Note that the 'raw'
  245. Xlibrary bank voice data does NOT have to match the data that is
  246. Xreally sent to the synthesizer (by the ed_sedit and ed_sone functions).
  247. XFor example, the DEP-5 does not have names as part of the voice data,
  248. Xbut that does not prevent glib from maintaining and storing (in the files)
  249. Xvoice names.  This holds for the DW-8000 as well.
  250. X
  251. XThe ed_numof function is called to convert the voice number to the
  252. Xtext that is displayed on the librarian screen.  This can handle
  253. Xthe odd numbering convention of the DW-8000.  If ed_numof==NULL, the
  254. Xnumber is used as-is.  Otherwise, ed_numof is called with the voice
  255. Xnumber MINUS 1 (i.e. 0-based); ed_numof should return a string
  256. Xcontaining the desired display.  Likewise, the ed_cvtnum function is
  257. Xused to convert user input from an odd numbering system to the standard
  258. Xsequential internal representation (0 to whatever).
  259. X
  260. XThe editor screen is controlled by two arrays, ed_labels and ed_params.
  261. Xed_labels contains arbitrary screen labels, in the following structure:
  262. X
  263. Xstruct labelinfo {
  264. X    int l_row;    /* 0-based */
  265. X    int l_col;    /* 0-based */
  266. X    char *l_text;
  267. X};
  268. X
  269. XThe ed_params array is used to specify the parameters that the user can peruse
  270. Xand change in the edit screen, and looks like this (one for each parameter):
  271. X
  272. Xstruct paraminfo {
  273. X    char *p_name;        /* the parameter name */
  274. X    char *p_label;        /* on-screen label (possibly NULL) */
  275. X    int p_lrow;        /* position for printing label */
  276. X    int p_lcol;
  277. X    int p_vrow;        /* position for printing value */
  278. X    int p_vcol;
  279. X    char *((*p_tovis)());    /* function converts value to on-screen text*/
  280. X    int p_min;        /* minimum parameter value */
  281. X    int p_max;        /* maximum parameter value */
  282. X    int p_val;        /* parameter value */
  283. X    int p_flags;        /* flag to enable/disable parameter */
  284. X};
  285. X
  286. XThe editor calls p_tovis with a parameter value, and expects that function
  287. Xto pass back a string which contains what should be displayed on the
  288. Xscreen for that value.  Often, this is just an 'sprintf' of the value,
  289. Xor perhaps the value offset by something.  Or, it could be some text
  290. Xthat represents the value (e.g. "on" for 1 and "off" for 0).  Or, it could
  291. Xbe something more interesting, e.g. a picture of the voice algorithm.
  292. XThe parameter value strings can make use of cursor motion, by including the
  293. Xsequences ~d,~u,~l,~r to go down,up,left,right.  The dx100 and dep5 editors
  294. Xuse this to handle the display of the algorithm drawings.
  295. X
  296. XA parameter can be 'disabled' by setting p_flags to non-zero.  The p_tovis
  297. Xfunction can set the external variable 'Redraw' to 1 if it wants to force
  298. Xthe entire editor screen to be redrawn (e.g. after a parameter has been
  299. Xdisabled).
  300. X
  301. XSupport for a mouse has been added, although it is currently disabled
  302. Xfor the Atari, since I was having various hassles getting it under control.
  303. XIt did work, but had various quirks.
  304. X
  305. XMouse support for the Amiga was added, and appears to work after fixing
  306. Xa few problems in glib.c, so it may be possible to enable the Atari mouse
  307. Xsupport now.
  308. X
  309. X                             ...Tim Thompson...twitch!glimmer!tjt...
  310. X
  311. X[notes from Ed Wilts, ewilts%Janus.MtRoyal.AB.CA@Ucnet.UCalgary.CA,
  312. X on the Amiga version for the D-10]
  313. X
  314. X...  The problem I had in getting it
  315. Xgoing was more in the execution than the compilation.  Without a sufficiently
  316. Xlarge stack, you will get highly intermittent results, and depending on the
  317. Xstate of the moon and the time of day, gurus.  I was getting frequent timeouts
  318. Xreading from the D-10 and sometimes the data would be all read but not in the
  319. Xproper order.  I was getting quite frustrated for a while...
  320. X
  321. XMy stack was originally 4000 - the default.  I boosted it to 8192 with no
  322. Xgreater results, and finally went to 32768 and now it seems to work.  At least
  323. XI can read from the D-10 consistently. ...
  324. END_OF_FILE
  325. if test 12157 -ne `wc -c <'PORTING'`; then
  326.     echo shar: \"'PORTING'\" unpacked with wrong size!
  327. fi
  328. # end of 'PORTING'
  329. fi
  330. if test -f 'k1multi.mnu' -a "${1}" != "-c" ; then 
  331.   echo shar: Will not clobber existing file \"'k1multi.mnu'\"
  332. else
  333. echo shar: Extracting \"'k1multi.mnu'\" \(10993 characters\)
  334. sed "s/^X//" >'k1multi.mnu' <<'END_OF_FILE'
  335. X/* $Id: k1multi.mnu,v 1.6 89/05/06 17:13:27 lee Exp $
  336. X * GLIB - a Generic LIBrarian and editor for synths
  337. X *
  338. X * K1 Patch Librarian
  339. X *
  340. X * Adapted for K1 from Kesti's D10 version by Greg Lee
  341. X * $Log:    k1multi.mnu,v $
  342. X * Revision 1.6  89/05/06  17:13:27  lee
  343. X * rel. to comp.sources.misc
  344. X * 
  345. X */
  346. X
  347. X#include "glib.h"
  348. X#include "k1vis.h"
  349. X
  350. X#define K1MULTISIZE 75
  351. X#define K1SINGLESIZE 87
  352. X#define RESERVESIZE 0
  353. X
  354. Xextern char sngnames[64][11];
  355. X
  356. X/* This array contains arbitrary screen labels */
  357. Xstruct labelinfo Lk1m[] = {
  358. X
  359. X#MENU for multi
  360. X            volume %
  361. X
  362. X
  363. X
  364. X
  365. X   A.........   B................  C.............  D.....................
  366. X   single       zn lo zn hi vel sw poly mode rcvch trnsps tune level output
  367. X |-------------|-----|-----|------|----|----|-----|------|----|-----|------|
  368. X
  369. X1  %              %     %     %     %    %     %     %     %     %     %
  370. X2  %              %     %     %     %    %     %     %     %     %     %
  371. X3  %              %     %     %     %    %     %     %     %     %     %
  372. X4  %              %     %     %     %    %     %     %     %     %     %
  373. X5  %              %     %     %     %    %     %     %     %     %     %
  374. X6  %              %     %     %     %    %     %     %     %     %     %
  375. X7  %              %     %     %     %    %     %     %     %     %     %
  376. X8  %              %     %     %     %    %     %     %     %     %     %
  377. X
  378. X
  379. X
  380. X
  381. X
  382. X Press SPACE BAR to sound note %   at volume %   for duration %  on channel % .
  383. X#END
  384. X
  385. X-1,-1,NULL
  386. X};
  387. X
  388. Xchar *vismltnum();
  389. X
  390. Xstruct paraminfo Pk1m[] = {
  391. X
  392. X/*NAME        TYPE        POS    MAX    OFFSET    MASK    SHIFT    ADHOC*/
  393. X
  394. X#O volume    pnum        %%    99    10
  395. X
  396. X#O single1    mltnum        %%    63    11
  397. X#O zonelo1    cpitch        %%    127    19
  398. X#O zonehi1    cpitch        %%    127    27
  399. X#O velosw1    velosw        %%    2    43    0x30    4
  400. X#O poly1    poly        %%    9    35    0x0F
  401. X#O modem1    mode        %%    2    35    0x40    6    *1
  402. X/* 2nd bit below goes above */
  403. X#O moden1    num        --    1    43    0x40    6    *2
  404. X#O rcvch1    pnum        %%    15    43    0x0F
  405. X#O trnsps1    keyshift    %%    48    51
  406. X#O tune1    finetune    %%    100    59
  407. X#O level1    num        %%    100    67
  408. X#O output1    pan        %%    2    35    0x30    4
  409. X
  410. X#O single2    mltnum        %%    63    12
  411. X#O zonelo2    cpitch        %%    127    20
  412. X#O zonehi2    cpitch        %%    127    28
  413. X#O velosw2    velosw        %%    2    44    0x30    4
  414. X#O poly2    poly        %%    9    36    0x0F
  415. X#O modem2    mode        %%    2    36    0x40    6    *1
  416. X#O moden2    num        --    1    44    0x40    6    *2
  417. X#O rcvch2    pnum        %%    15    44    0x0F
  418. X#O trnsps2    keyshift    %%    48    52
  419. X#O tune2    finetune    %%    100    60
  420. X#O level2    num        %%    100    68
  421. X#O output2    pan        %%    2    36    0x30    4
  422. X
  423. X#O single3    mltnum        %%    63    13
  424. X#O zonelo3    cpitch        %%    127    21
  425. X#O zonehi3    cpitch        %%    127    29
  426. X#O velosw3    velosw        %%    2    45    0x30    4
  427. X#O poly3    poly        %%    9    37    0x0F
  428. X#O modem3    mode        %%    2    37    0x40    6    *1
  429. X#O moden3    num        --    1    45    0x40    6    *2
  430. X#O rcvch3    pnum        %%    15    45    0x0F
  431. X#O trnsps3    keyshift    %%    48    53
  432. X#O tune3    finetune    %%    100    61
  433. X#O level3    num        %%    100    69
  434. X#O output3    pan        %%    2    37    0x30    4
  435. X
  436. X#O single4    mltnum        %%    63    14
  437. X#O zonelo4    cpitch        %%    127    22
  438. X#O zonehi4    cpitch        %%    127    30
  439. X#O velosw4    velosw        %%    2    46    0x30    4
  440. X#O poly4    poly        %%    9    38    0x0F
  441. X#O modem4    mode        %%    2    38    0x40    6    *1
  442. X#O moden4    num        --    1    46    0x40    6    *2
  443. X#O rcvch4    pnum        %%    15    46    0x0F
  444. X#O trnsps4    keyshift    %%    48    54
  445. X#O tune4    finetune    %%    100    62
  446. X#O level4    num        %%    100    70
  447. X#O output4    pan        %%    2    38    0x30    4
  448. X
  449. X#O single5    mltnum        %%    63    15
  450. X#O zonelo5    cpitch        %%    127    23
  451. X#O zonehi5    cpitch        %%    127    31
  452. X#O velosw5    velosw        %%    2    47    0x30    4
  453. X#O poly5    poly        %%    9    39    0x0F
  454. X#O modem5    mode        %%    2    39    0x40    6    *1
  455. X#O moden5    num        --    1    47    0x40    6    *2
  456. X#O rcvch5    pnum        %%    15    47    0x0F
  457. X#O trnsps5    keyshift    %%    48    55
  458. X#O tune5    finetune    %%    100    63
  459. X#O level5    num        %%    100    71
  460. X#O output5    pan        %%    2    39    0x30    4
  461. X
  462. X#O single6    mltnum        %%    63    16
  463. X#O zonelo6    cpitch        %%    127    24
  464. X#O zonehi6    cpitch        %%    127    32
  465. X#O velosw6    velosw        %%    2    48    0x30    4
  466. X#O poly6    poly        %%    9    40    0x0F
  467. X#O modem6    mode        %%    2    40    0x40    6    *1
  468. X#O moden6    num        --    1    48    0x40    6    *2
  469. X#O rcvch6    pnum        %%    15    48    0x0F
  470. X#O trnsps6    keyshift    %%    48    56
  471. X#O tune6    finetune    %%    100    64
  472. X#O level6    num        %%    100    72
  473. X#O output6    pan        %%    2    40    0x30    4
  474. X
  475. X#O single7    mltnum        %%    63    17
  476. X#O zonelo7    cpitch        %%    127    25
  477. X#O zonehi7    cpitch        %%    127    33
  478. X#O velosw7    velosw        %%    2    49    0x30    4
  479. X#O poly7    poly        %%    9    41    0x0F
  480. X#O modem7    mode        %%    2    41    0x40    6    *1
  481. X#O moden7    num        --    1    49    0x40    6    *2
  482. X#O rcvch7    pnum        %%    15    49    0x0F
  483. X#O trnsps7    keyshift    %%    48    57
  484. X#O tune7    finetune    %%    100    65
  485. X#O level7    num        %%    100    73
  486. X#O output7    pan        %%    2    41    0x30    4
  487. X
  488. X#O single8    mltnum        %%    63    18
  489. X#O zonelo8    cpitch        %%    127    26
  490. X#O zonehi8    cpitch        %%    127    34
  491. X#O velosw8    velosw        %%    2    50    0x30    4
  492. X#O poly8    poly        %%    9    42    0x0F
  493. X#O modem8    mode        %%    2    42    0x40    6    *1
  494. X#O moden8    num        --    1    50    0x40    6    *2
  495. X#O rcvch8    pnum        %%    15    50    0x0F
  496. X#O trnsps8    keyshift    %%    48    58
  497. X#O tune8    finetune    %%    100    66
  498. X#O level8    num        %%    100    74
  499. X#O output8    pan        %%    2    42    0x30    4
  500. X
  501. X"autopitch",    NULL,    -1,-1, %%, visnum,         0, 127, 60, 0,
  502. X"autovol",    NULL,    -1,-1, %%, visnum,         0, 127, 63, 0,
  503. X"autodur",    NULL,    -1,-1, %%, visnum,         1,  20,  5, 0,
  504. X"autochan",    NULL,    -1,-1, %%, visnum,         1,  16,  1, 0,
  505. X
  506. XNULL,        NULL,    -1,-1, -1, -1, visnum,         0,   0, 0, 0
  507. X};
  508. X
  509. X/*
  510. X * k1mnum
  511. X *
  512. X * Convert a voice number (0 to 127) to the string displayed in the
  513. X * librarian (ie. A1 to D8 for multi, to d8 for singles).
  514. X */
  515. X
  516. Xchar *
  517. Xk1mnum(n)
  518. X{
  519. X    static char v[4];
  520. X
  521. X    if ( n < 0 || n > 63 )
  522. X        return("???");
  523. X
  524. X    v[0] = 'A' + (n >> 3);
  525. X    if (v[0] > 'D') v[0] += ' ' - 4;
  526. X
  527. X    (void)sprintf(v+1, "%d", (n % 8) + 1);
  528. X
  529. X    return(v);
  530. X}
  531. X
  532. Xchar *
  533. Xvismltnum(n)
  534. X{    static char numnam[15];
  535. X
  536. X    strcpy(numnam, k1mnum(n));
  537. X    if (sngnames[n][0] > ' ') {
  538. X        strcat(numnam, " ");
  539. X        strcat(numnam, sngnames[n]);
  540. X    }
  541. X    return(numnam);
  542. X}
  543. X
  544. X/*
  545. X * k1nummlt
  546. X *
  547. X * Convert a display-style voice number (A1 to d8) to internal
  548. X * format (0 to 127).
  549. X */
  550. X
  551. Xk1nummlt(s)
  552. Xchar *s;
  553. X{
  554. X
  555. X    int ld, rd;
  556. X
  557. X    rd = s[0] - 'A';
  558. X    if (rd > 3) rd -= ' ' - 4;
  559. X    if (rd < 0 || rd > 7) return(-1);
  560. X
  561. X    (void)sscanf(s+1, "%d", &ld);
  562. X    if (ld < 1 || ld > 8) return(-1);
  563. X
  564. X    return((rd << 3) + ld - 1);
  565. X
  566. X}
  567. X
  568. X/*
  569. X * k1mdin
  570. X *
  571. X * Take library bank 'data' and stuff values in the P array, by using
  572. X * the setval function.
  573. X */
  574. X
  575. Xk1mdin(data)
  576. Xchar *data;
  577. X{
  578. X    /* The first RESERVESIZE bytes are reserved (arbitrarily) for the voice name */
  579. X#SETVAL
  580. X}
  581. X
  582. X/*
  583. X * k1mdout
  584. X *
  585. X * Take (possibly changed) parameters values out of the P array and
  586. X * put them back into the library bank 'data'.
  587. X */
  588. X
  589. Xk1mdout(data)
  590. Xchar *data;
  591. X{
  592. X#GETVAL
  593. X}
  594. X
  595. Xk1send1(function, voice)
  596. X{
  597. X    if (Nvoices == 32) voice += 64;
  598. X
  599. X    sendmidi(0xf0);
  600. X    sendmidi(0x40);        /* Kawai id */
  601. X    sendmidi(Channel - 1);    /* channel = 1 to 16 */
  602. X    sendmidi(function);    /* function */
  603. X    sendmidi(0x00);        /* group */
  604. X    sendmidi(0x03);        /* machine id number of K1 */
  605. X    sendmidi(0x00);        /* subcommand 1 = internal */
  606. X    sendmidi(voice);    /* subcommand 2 = voice 1 */
  607. X}
  608. X
  609. X/*
  610. X * k1msedit
  611. X *
  612. X * Send a single voice to the edit buffer of the K1.  This will be whatever
  613. X * voice is currently selected.
  614. X * (So far as I know, one can't do this;  this is here pro forma. -- gl)
  615. X */
  616. X
  617. Xk1msedit(data)
  618. Xchar *data;
  619. X{
  620. X/*
  621. X    int cksum;
  622. X    int n, dumpsize;
  623. X
  624. X    k1send1(0x20, 0);
  625. X    cksum = 0xa5;
  626. X
  627. X    if (Nvoices == 32) dumpsize = K1MULTISIZE;
  628. X    else dumpsize = K1SINGLESIZE;
  629. X
  630. X    for(n = 0; n < dumpsize; n++) {
  631. X        sendmidi(data[n] & 0x7f);
  632. X        cksum += data[n] & 0x7f;
  633. X    }
  634. X    sendmidi(cksum & 0x7f);
  635. X    sendmidi(EOX);
  636. X*/
  637. X}
  638. X
  639. X/*
  640. X * k1mnof
  641. X *
  642. X * Return a pointer to the voice name buried in library bank data.
  643. X */
  644. Xchar *
  645. Xk1mnof(data)
  646. Xchar *data;
  647. X{
  648. X    static char currbuff[11];
  649. X    char *p;
  650. X    int m;
  651. X
  652. X    p = currbuff;
  653. X    for ( m = 0 ; m < 10 ; m++ )
  654. X        *p++ = data[m];
  655. X    *p = '\0';
  656. X    return(currbuff);
  657. X}
  658. X
  659. X/*
  660. X * k1msnof
  661. X *
  662. X * Set the voice name buried in data to name.
  663. X */
  664. Xk1msnof(data,name)
  665. Xchar *data;
  666. Xchar *name;
  667. X{
  668. X    char *p;
  669. X    int m;
  670. X
  671. X    for ( p = name, m = 0 ; *p != '\0' && m < 10 ; p++, m++ )
  672. X        data[m] = *p;
  673. X    for ( ; m < 10 ; m++ )
  674. X        data[m] = ' ';
  675. X}
  676. X
  677. X/* k1msone - send a single voice to the K1 */
  678. Xk1msone(iv, data)
  679. Xint iv;
  680. Xchar *data;
  681. X{
  682. X    int cksum;
  683. X    int n, dumpsize;
  684. X
  685. X    k1send1(0x20, iv);
  686. X    cksum = 0xa5;
  687. X
  688. X    if (Nvoices == 32) dumpsize = K1MULTISIZE;
  689. X    else dumpsize = K1SINGLESIZE;
  690. X
  691. X    for(n = 0; n < dumpsize; n++) {
  692. X        sendmidi(data[n] & 0x7f);
  693. X        cksum += data[n] & 0x7f;
  694. X    }
  695. X    sendmidi(cksum & 0x7f);    /* checksum */
  696. X    sendmidi(EOX);
  697. X
  698. X    return(0);
  699. X}
  700. X
  701. X/* k1mgbulk - Request and read a bulk dump from the K1 */
  702. Xk1mgbulk(data)
  703. Xchar *data;
  704. X{
  705. X    static    char Buff[BUFSIZ];
  706. X    int n, v, b2, ret = 1;
  707. X    long begin, toolong;
  708. X    int dumpsize;
  709. X    
  710. X    (void)sprintf(Buff,"\nA: ");
  711. X    windstr(Buff);
  712. X
  713. X    if (Nvoices == 32) dumpsize = K1MULTISIZE;
  714. X    else dumpsize = K1SINGLESIZE;
  715. X
  716. X    for(v = 0; v < Nvoices; v++) {
  717. X
  718. X        flushmidi();
  719. X
  720. X        if(v == 64) {
  721. X            (void)sprintf(Buff,"\nB: ");
  722. X            windstr(Buff);
  723. X        }
  724. X        if((((v > 63) ? (v - 64) : v) % 10) != 0) {
  725. X            (void)sprintf(Buff, ".");
  726. X        } else {
  727. X            (void)sprintf(Buff,"%d", (((v > 63) ? (v - 64) : v) / 10));
  728. X        }
  729. X        windstr(Buff);
  730. X
  731. X    /* request the dump */
  732. X        if (!synthinfileflag) {
  733. X            k1send1(0, v);
  734. X            sendmidi(EOX);
  735. X        }
  736. X    
  737. X    /* set up timeout */
  738. X        begin = milliclock();
  739. X        toolong = begin + (1000 * TIMEOUT);
  740. X    
  741. X    /* read header */
  742. X        for(n = 0; n < 8; ) {
  743. X            if ( STATMIDI ) {
  744. X                b2 = (getmidi() & 0xff);
  745. X                /* burn active sensing and timing clock */
  746. X                if((b2 != 0xfe) && (b2 != 0xf8))
  747. X                    n++;
  748. X            } else {
  749. X                if ( milliclock() > toolong ) {
  750. X                    Reason = "Timeout waiting for header";
  751. X                    goto getout;
  752. X                }
  753. X            }
  754. X        }
  755. X
  756. X    /* read data */
  757. X        for(n = 0; n < dumpsize; ) {
  758. X            if ( STATMIDI ) {
  759. X                b2 = (getmidi() & 0xff);
  760. X                /* burn active sensing and timing clock */
  761. X                if((b2 != 0xfe) && (b2 != 0xf8)) {
  762. X                    VOICEBYTE(data,v,n) = b2;
  763. X                    n++;
  764. X                }
  765. X            } else {
  766. X                if ( milliclock() > toolong ) {
  767. X                    Reason = "Timeout reading data";
  768. X                    goto timeout;
  769. X                }
  770. X            }
  771. X        }
  772. X
  773. X    timeout:
  774. X        if ( n != dumpsize ) {
  775. X            Reason = "Timeout reading data!";
  776. X            goto getout;
  777. X        }
  778. X
  779. X    /* read checksum */
  780. X        for(n = 0; n < 1; ) {
  781. X            if ( STATMIDI ) {
  782. X                b2 = (getmidi() & 0xff);
  783. X                /* burn active sensing and timing clock */
  784. X                if((b2 != 0xfe) && (b2 != 0xf8))
  785. X                    n++;
  786. X            } else {
  787. X                if ( milliclock() > toolong ) {
  788. X                    Reason = "Timeout reading checksum";
  789. X                    goto getout;
  790. X                }
  791. X            }
  792. X        }
  793. X
  794. X    /* read EOX */
  795. X        for(n = 0; n < 1; ) {
  796. X            if ( STATMIDI ) {
  797. X                b2 = (getmidi() & 0xff);
  798. X                /* burn active sensing and timing clock */
  799. X                if((b2 != 0xfe) && (b2 != 0xf8))
  800. X                    if ( b2 != EOX ) {
  801. X                        (void)sprintf(Buff,"EOX not received (%X)\n", b2);
  802. X                        Reason = Buff;
  803. X                        goto getout;
  804. X                    }
  805. X                    n++;
  806. X            } else {
  807. X                if ( milliclock() > toolong ) {
  808. X                    Reason = "Timeout reading EOX";
  809. X                    goto getout;
  810. X                }
  811. X            }
  812. X        }
  813. X
  814. X    } /* go back for another voice */
  815. X
  816. X    Reason = "";
  817. X    ret = 0;    /* all's well */
  818. X
  819. Xgetout:
  820. X    return(ret);
  821. X}
  822. X
  823. X/* k1msbulk - send a bulk dump to the K1 */
  824. Xk1msbulk(data)
  825. Xchar *data;
  826. X{
  827. X    static char Buff[BUFSIZ];
  828. X    int v, n, databyte, curoff, dumpsize;
  829. X    int cksum;
  830. X
  831. X    (void)sprintf(Buff,"\nA: ");
  832. X    windstr(Buff);
  833. X
  834. X    if (Nvoices == 32) dumpsize = K1MULTISIZE;
  835. X    else dumpsize = K1SINGLESIZE;
  836. X
  837. X    curoff = 0;
  838. X    for(v = 0; v < Nvoices ; v++) {
  839. X        if(v == 64) {
  840. X            (void)sprintf(Buff,"\nB: ");
  841. X            windstr(Buff);
  842. X        }
  843. X        if((((v > 63) ? (v - 64) : v) % 10) != 0) {
  844. X            (void)sprintf(Buff, ".");
  845. X        } else {
  846. X            (void)sprintf(Buff,"%d", (((v > 63) ? (v - 64) : v) / 10));
  847. X        }
  848. X
  849. X        windstr(Buff);
  850. X        k1send1(0x20, v);
  851. X        cksum = 0xa5;
  852. X
  853. X        for(n = 0; n < dumpsize; n++) {
  854. X            databyte = data[n + curoff] & 0x7f;
  855. X            sendmidi(databyte);
  856. X            cksum += databyte;
  857. X        }
  858. X        sendmidi(cksum & 0x7f);    /* checksum */
  859. X        sendmidi(EOX);
  860. X        curoff += Voicesize;
  861. X    }
  862. X    return(0);
  863. X}
  864. X
  865. X/* end */
  866. END_OF_FILE
  867. if test 10993 -ne `wc -c <'k1multi.mnu'`; then
  868.     echo shar: \"'k1multi.mnu'\" unpacked with wrong size!
  869. fi
  870. # end of 'k1multi.mnu'
  871. fi
  872. if test -f 'pc-ints.asm' -a "${1}" != "-c" ; then 
  873.   echo shar: Will not clobber existing file \"'pc-ints.asm'\"
  874. else
  875. echo shar: Extracting \"'pc-ints.asm'\" \(12452 characters\)
  876. sed "s/^X//" >'pc-ints.asm' <<'END_OF_FILE'
  877. X@ab    equ 6        ;use big model
  878. X; $Id: pc-ints.asm,v 1.6 89/05/06 17:13:38 lee Exp $
  879. X;
  880. X; the following constants are hardware specific to the MPU401 & OP4000
  881. X; MIDI interface controllers
  882. X; $Log:    pc-ints.asm,v $
  883. X; Revision 1.6  89/05/06  17:13:38  lee
  884. X; rel. to comp.sources.misc
  885. X; 
  886. X; 
  887. X;
  888. XBASE_ADDRESS_MPU     equ 330h
  889. XSTATUS_PORT_MPU     equ BASE_ADDRESS_MPU  + 1
  890. XCOMMAND_PORT_MPU     equ BASE_ADDRESS_MPU  + 1
  891. XDATA_PORT_MPU         equ BASE_ADDRESS_MPU  + 0
  892. XTx_EMT             equ 40h    ;midi transmitter ready for more data
  893. XRx_NEMT            equ 80h    ;midi receiver has data ready
  894. XMPU_INT            equ 2
  895. XMPU_INT_MASK        equ 4
  896. X;
  897. X; the remaining constants are for the AT&T PC6300 and compatible PC's
  898. X;
  899. XTIMER_INT        equ 0
  900. XTIMER_INT_MASK        equ 1
  901. XHW_INT_MASK        equ MPU_INT_MASK OR TIMER_INT_MASK
  902. XINT_CTLR_PORT        equ 20h    ;port to send EOI command to
  903. XINT_CTLR_IMR         equ 21h    ;port to mask interrupts
  904. XEOI_CODE        equ 20h    ;EOI command
  905. XT_55MS       equ    0000h        ; 8253 value for 55 ms
  906. XT_5MS       equ    174dh        ; 8253 value for 5 ms
  907. XTIC_55MS   equ    11        ; Number of timer tics to equal 55 ms
  908. XPIT_MODE   equ    36h    ; 8253 mode: 00 11 011 0 -> cntr0,LSB/MSB,mode 3,binary
  909. XPIT_CNT0   equ    40h        ; Counter 0 port for 8253 PIT
  910. XPIT_CTRL   equ    43h        ; Control port for 8253 PIT
  911. XUSER_TMR   equ    1ch        ; User Timer (55 ms) Int. Vector
  912. X;
  913. X
  914. X;********************
  915. X;**   macros       **
  916. X;********************
  917. X;
  918. Xc_in    macro            ;this macro sets up a stack frame
  919. X    push    bp        ;must save bp reg for 'c' progs
  920. X    mov    bp, sp            ;set up frame pointer
  921. X    push di
  922. X    push si            ;save register vars
  923. X    endm
  924. X;
  925. Xc_out    macro            ;This macro cleans up for return to 'C'
  926. X    pop si
  927. X    pop di
  928. X    mov sp, bp
  929. X    pop    bp            ;restore caller's frame pointer
  930. X    cld                ;clear direction flag 
  931. X    ret                ;and return
  932. X    endm
  933. X;
  934. Xpush_all_regs    macro
  935. X    push    es
  936. X    push    ds
  937. X    push    dx
  938. X    push    cx
  939. X    push    bx
  940. X    push    si
  941. X    push    di
  942. X    push    ax
  943. X    push    bp
  944. X    endm
  945. X;
  946. Xpop_all_regs    macro
  947. X    pop    bp
  948. X    pop    ax
  949. X    pop    di
  950. X    pop    si
  951. X    pop    bx
  952. X    pop    cx
  953. X    pop    dx
  954. X    pop    ds
  955. X    pop    es
  956. X    endm
  957. X;
  958. Xenable_IMR    macro num        ;this macro clears (enables)
  959. X                    ;interrupts in the interrupt mask reg
  960. X    in        al, INT_CTLR_IMR    ;read in current int mask
  961. X    and        al, 0ffh - num        ;clear the requested IMR bit
  962. X    out        INT_CTLR_IMR, al    ;and write it back out
  963. X    endm
  964. X;
  965. Xdisable_IMR    macro num        ;disable interrupts in the IMR
  966. X    in        al, INT_CTLR_IMR    ;read in current int mask
  967. X    or        al, num            ;set the requested IMR bit
  968. X    out        INT_CTLR_IMR, al    ;and write it out
  969. X    endm
  970. X;
  971. Xack_int    macro                ;this macro sends non-specific EOI
  972. X                        ;to the int controller chip in the PC
  973. X    mov al, EOI_CODE
  974. X    out INT_CTLR_PORT, al
  975. X    sti
  976. X    endm
  977. X;
  978. X
  979. X;************************************************************
  980. X;**                                                        **
  981. X;** DATA GROUP DECLARATION                                 **
  982. X;**                                                        **
  983. X;************************************************************
  984. X;
  985. X    
  986. Xdgroup    group    data
  987. Xdata    segment    word public 'data'
  988. X    assume    ds:dgroup
  989. X;
  990. X; --- The following vars are used to manage a very small stack
  991. X;     that is used for interrupt enable/disable stacking
  992. X;
  993. XINT_STACK_SIZE        equ    8 * 1
  994. Xint_stack        db    (INT_STACK_SIZE/8) dup ('intstack')
  995. Xint_stack_pointer     dw    0
  996. X;
  997. X; --- The following provide a circular character buffer used to
  998. X;     store data received from the MIDI interface
  999. X;
  1000. XBUFFER_SIZE        equ    512
  1001. X_wrt_index        dw    0
  1002. X_rd_index        dw    0
  1003. X_midi_buffer        db    BUFFER_SIZE dup (0)
  1004. Xpublic _wrt_index
  1005. Xpublic _rd_index
  1006. Xpublic _midi_buffer
  1007. X;
  1008. X; --- The following vars are used to keep a running tally of the
  1009. X;     programmable timer ticks.
  1010. X;
  1011. X_hzcount        dd    0
  1012. Xint_cnt            dw     0
  1013. Xpublic    _hzcount
  1014. X;
  1015. Xdata    ends
  1016. X;
  1017. X
  1018. X;************************************************************
  1019. X;**                                                        **
  1020. X;** CODE SEGMENT                                           **
  1021. X;**                                                        **
  1022. X;**                                                        **
  1023. X;************************************************************
  1024. X;
  1025. X;
  1026. X    extrn _fatal_dos_handler:far    ;'C' routine to handle DOS errors
  1027. X    extrn _bye:far            ; exit routine for Ctl-brk
  1028. X
  1029. X_code segment byte public 'code'
  1030. X    assume cs:_code
  1031. X    public     _ctl_brk
  1032. X    public     _asm_fatal_dos_handler
  1033. X    public     _disable_ints
  1034. X    public     _enable_ints
  1035. X    public     _init_enable_MPU
  1036. X    public     _init_enable_TIMER
  1037. X    public     _reset_TIMER
  1038. X    public     _write_data_MPU
  1039. X    public     _read_MPU
  1040. X    public     _midi_isr
  1041. X    public     _tick_isr
  1042. X
  1043. X;
  1044. X;************************************************************
  1045. X;**                                                        **
  1046. X;** INTERRUPT HANDLERS                                     **
  1047. X;**                                                        **
  1048. X;**                                                        **
  1049. X;************************************************************
  1050. X_ctl_brk    proc    far
  1051. X;
  1052. X;    Control-Break Interrupt Service Routine
  1053. X;
  1054. Xctl_st: cli            ; make sure no interrupts
  1055. X    mov    ax,ds
  1056. X    mov    ss,ax        ; ss = ds :: so chkstk() doesn't fail in quit()
  1057. X    mov    sp,0fffeh    ;  and sp = hi mem
  1058. X    mov    ax,1        ; exit code
  1059. X    sti            ; turn interrupts back on
  1060. X    push    ax
  1061. X    call    _bye
  1062. X    pop    bp        ; not needed, never returns here
  1063. X    iret            ;  or here
  1064. X_ctl_brk    endp
  1065. X;
  1066. X;    Fatal Dos Error Interrupt Service Routine
  1067. X;
  1068. X_asm_fatal_dos_handler proc far
  1069. X    push_all_regs        ;save machine state
  1070. X    push    di
  1071. X    push    ax        ;push args for function
  1072. X    mov    ax, dgroup
  1073. X    mov    ds, ax        ;address data segment
  1074. X    mov    es, ax        ;and extra segmant
  1075. X    call    _fatal_dos_handler ;handler(ax, di)
  1076. X    pop    ax
  1077. X    pop    ax
  1078. X    pop_all_regs
  1079. X    mov    al,0        ;tell DOS to ignore error
  1080. X    iret
  1081. X_asm_fatal_dos_handler endp
  1082. X;
  1083. X;
  1084. X;************************************************************
  1085. X;** MIDI_ISR                                               **
  1086. X;** This is the MPU int service routine                    **
  1087. X;** It reads data from MPU data port until there is no more** 
  1088. X;** and stores in a circular buffer               **
  1089. X;************************************************************
  1090. X;
  1091. X_midi_isr    proc    far
  1092. X    push_all_regs                ;save machine state
  1093. X    mov    ax, dgroup
  1094. X    mov    ds, ax
  1095. X    disable_IMR MPU_INT_MASK
  1096. X    sti
  1097. Xdo_another:
  1098. X    mov    dx, DATA_PORT_MPU
  1099. X    in    al, dx        ;read in the interrupt data from MPU
  1100. X
  1101. X        inc    _wrt_index            ;bump up write pointer
  1102. X        cmp    _wrt_index, 01ffh        ;is index at top of buff?
  1103. X        jle    wrt_index_ok
  1104. X        mov    _wrt_index, 0            ;if yes, wraparound to bottom
  1105. Xwrt_index_ok:                    ;of buffer 
  1106. X        mov    bx, _wrt_index
  1107. X        mov    _midi_buffer[bx], al        ;move data into buffer
  1108. X
  1109. X        mov dx, STATUS_PORT_MPU            ;DX = &status port
  1110. X        in    al, dx                ;read status port
  1111. X        and al, Rx_NEMT                ;is there data to read?
  1112. X    jz    do_another            ;go back if so
  1113. X;isr return
  1114. X    cli                    ;turn off system ints
  1115. X    enable_IMR MPU_INT_MASK
  1116. X    ack_int                    ;and acknowlege interrupt
  1117. X    pop_all_regs                ;restore machine state
  1118. X    iret                    ;and leave
  1119. X_midi_isr    endp
  1120. X;
  1121. X;********************************************************************
  1122. X;*    TICK_ISR
  1123. X;*    The interrupt service routine for the programmable timer.
  1124. X;*    Timer is currently set at 5 ms. intervals.
  1125. X;********************************************************************
  1126. X;
  1127. X_tick_isr     proc far
  1128. X;
  1129. Xtmr_st:    push    ds
  1130. X    push    ax
  1131. X    mov    ax, dgroup
  1132. X    mov    ds, ax        ;must have our data segment
  1133. X    disable_IMR TIMER_INT_MASK
  1134. X    sti
  1135. X    add    word ptr _hzcount, 1
  1136. X    adc    word ptr _hzcount + 2, 0
  1137. X    inc    int_cnt
  1138. X    cmp    int_cnt,TIC_55MS
  1139. X    jge    tm1
  1140. X    cli
  1141. X    enable_IMR TIMER_INT_MASK
  1142. X    ack_int
  1143. X    pop    ax
  1144. X    pop    ds
  1145. X    iret
  1146. X
  1147. Xtm1:    mov    int_cnt,0
  1148. X    int    USER_TMR
  1149. X    cli
  1150. X    enable_IMR TIMER_INT_MASK
  1151. X    ack_int
  1152. X    pop    ax
  1153. X    pop    ds
  1154. X    iret
  1155. X_tick_isr endp
  1156. X
  1157. X
  1158. X;
  1159. X;************************************************************
  1160. X;** DISABLE_INTS()                                         **
  1161. X;** Called to disable interrupts.  stacks old int          **
  1162. X;** status before disabling, so that nesting is            **
  1163. X;** preserved.                                             **
  1164. X;************************************************************
  1165. X;
  1166. X_disable_ints proc far
  1167. X    cli
  1168. X        in    al, INT_CTLR_IMR    ;read in current int mask
  1169. X    mov    dl, al            ;move it to dl
  1170. X    and    dl, HW_INT_MASK        ;extract the bit for MPU ints
  1171. X    mov    bx, int_stack_pointer    ;get current stack pointer
  1172. X    mov    int_stack[bx], dl    ;store out int status there
  1173. X    inc    bx
  1174. X    mov    int_stack_pointer, bx    ;write back new stack pointer value
  1175. X    or    al, HW_INT_MASK        ;mask off int
  1176. X        out    INT_CTLR_IMR, al    ;and write it out
  1177. X    sti
  1178. X    ret
  1179. X_disable_ints endp
  1180. X;
  1181. X;************************************************************
  1182. X;** ENABLE_INTS()                                          **
  1183. X;** Restores whatever the int status was before            **
  1184. X;** DISABLE_INTS() was called.                             **
  1185. X;** Note that calls to enable and disable must be matched  **
  1186. X;** or chaos will occur                                    **
  1187. X;************************************************************
  1188. X;
  1189. X_enable_ints proc far
  1190. X    cli
  1191. X        in    al, INT_CTLR_IMR    ;read in current int mask
  1192. X    and    al, 0ffh - HW_INT_MASK     ; get all the bits except the ones
  1193. X                    ; for out ints
  1194. X    mov    bx, int_stack_pointer    ;get int stack pointer
  1195. X    dec    bx            ;move it down
  1196. X    mov    int_stack_pointer, bx    ;store it
  1197. X    or    al, int_stack[bx]    ;or in int status with old one
  1198. X        out    INT_CTLR_IMR, al    ;and write it out
  1199. X    sti                ;turn ints on now
  1200. X    ret
  1201. X_enable_ints endp
  1202. X;
  1203. X;************************************************************
  1204. X;** INIT_ENABLE_MPU()                                  **
  1205. X;** Starts up the MPU ints.                               **
  1206. X;**                                                        **
  1207. X;************************************************************
  1208. X;
  1209. X_init_enable_MPU proc far
  1210. X    cli
  1211. X    enable_IMR MPU_INT_MASK
  1212. X    sti
  1213. X    ret
  1214. X_init_enable_MPU endp
  1215. X;;
  1216. X;************************************************************
  1217. X;** INIT_ENABLE_TIMER()                                  **
  1218. X;** Starts up the TIMER ints.                               **
  1219. X;**                                                        **
  1220. X;************************************************************
  1221. X;
  1222. X_init_enable_TIMER proc far
  1223. X    cli
  1224. X; Set 8253 PIT for different timing
  1225. X;
  1226. X    mov    al,PIT_MODE
  1227. X    out    PIT_CTRL,al    ; Set 8253 mode
  1228. X    mov    ax,T_5MS
  1229. X    out    PIT_CNT0,al
  1230. X    mov    al,ah
  1231. X    out    PIT_CNT0,al    ; Set new timing
  1232. X    enable_IMR TIMER_INT_MASK
  1233. X    sti
  1234. X    ret
  1235. X_init_enable_TIMER endp 
  1236. X;
  1237. X;
  1238. X;************************************************************
  1239. X;** RESET_TIMER()                                          **
  1240. X;** Sets timer values back to what they were               **
  1241. X;**                                                        **
  1242. X;************************************************************
  1243. X_reset_TIMER    proc far
  1244. X
  1245. X    disable_IMR TIMER_INT_MASK
  1246. X    mov    al,PIT_MODE
  1247. X    out    PIT_CTRL,al    ; Set 8253 mode
  1248. X    mov    ax,T_55MS
  1249. X    out    PIT_CNT0,al
  1250. X    mov    al,ah
  1251. X    out    PIT_CNT0,al    ; Reset timing
  1252. X    enable_IMR TIMER_INT_MASK
  1253. X    ret
  1254. X_reset_TIMER    endp
  1255. X;
  1256. X
  1257. X;************************************************************
  1258. X;** WRITE_DATA_MPU(DATA)                                   **
  1259. X;** sends a byte to the MPU data port                      **
  1260. X;** waits for handshake                                    **
  1261. X;**                                                        **
  1262. X;************************************************************
  1263. X;
  1264. X;
  1265. X_write_data_MPU proc far
  1266. X    c_in
  1267. X    mov bx, @ab[bp]            ;get data byte in bl reg
  1268. X    call write_sub            ;and call fast sub
  1269. X    c_out                ;leave
  1270. X_write_data_MPU endp
  1271. X;
  1272. X;************************************************************
  1273. X;**                                                        **
  1274. X;**   write_sub                                            **
  1275. X;**   Writes data to MPU. on entry, byte in bl            **
  1276. X;**   ax, cx, cx destroyed                                 **
  1277. X;************************************************************
  1278. X;
  1279. Xwrite_sub proc near
  1280. X    mov dx, STATUS_PORT_MPU    ;set up pointer to MPU port
  1281. Xwrite_clear_loop:
  1282. X    in    al, dx
  1283. X    and al, Tx_EMT
  1284. X    jnz write_clear_loop
  1285. X    dec    dx            ;point to data reg
  1286. X    mov    al, bl
  1287. X    out    dx, al            ;send out the data
  1288. X    ret
  1289. Xwrite_sub endp
  1290. X;
  1291. X;************************************************************
  1292. X;** read_MPU()                                            **
  1293. X;** reads a byte from the MPU    eata port                   **
  1294. X;** waits for handshake                                    **
  1295. X;**                                                        **
  1296. X;************************************************************
  1297. X;
  1298. X_read_MPU proc far
  1299. X    c_in
  1300. Xread_clear_loop:
  1301. X    mov dx, STATUS_PORT_MPU    ;DX = &status port
  1302. X    in    al, dx
  1303. X    and al, Rx_NEMT
  1304. X    jnz read_clear_loop
  1305. X    dec    dx            ;point to data reg
  1306. X    in    al, dx
  1307. X    xor    ah, ah
  1308. X    c_out
  1309. X_read_MPU endp
  1310. X
  1311. X;
  1312. X
  1313. X_code    ends
  1314. X    end
  1315. X
  1316. END_OF_FILE
  1317. if test 12452 -ne `wc -c <'pc-ints.asm'`; then
  1318.     echo shar: \"'pc-ints.asm'\" unpacked with wrong size!
  1319. fi
  1320. # end of 'pc-ints.asm'
  1321. fi
  1322. if test -f 'pc-mach.c' -a "${1}" != "-c" ; then 
  1323.   echo shar: Will not clobber existing file \"'pc-mach.c'\"
  1324. else
  1325. echo shar: Extracting \"'pc-mach.c'\" \(11518 characters\)
  1326. sed "s/^X//" >'pc-mach.c' <<'END_OF_FILE'
  1327. X/* $Id: pc-mach.c,v 1.6 89/05/06 17:13:39 lee Exp $
  1328. X *
  1329. X * Glib - Generic LIBrarian and editor
  1330. X *
  1331. X * Machine dependent stuff for MIDI programs.
  1332. X * Time Thompson
  1333. X *
  1334. X * This is for MS-DOS machines.  The screen operations should
  1335. X * work okay, but the MIDI I/O needs to be worked on.  It may
  1336. X * or may not be fast enough on some machines. 
  1337. X * $Log:    pc-mach.c,v $
  1338. X * Revision 1.6  89/05/06  17:13:39  lee
  1339. X * rel. to comp.sources.misc
  1340. X * 
  1341. X */
  1342. X
  1343. X#include "glib.h"
  1344. X
  1345. Xint Rows = 24;
  1346. Xint Cols = 80;
  1347. X
  1348. Xchar *
  1349. Xalloc(n)
  1350. X{
  1351. X    char *p;
  1352. X
  1353. X    if ( (p=malloc((unsigned)n)) == (char *)NULL ) {
  1354. X        printf("*** Whoops *** alloc has failed?!?  No more memory!\n");
  1355. X        fflush(stdout);
  1356. X        bye();
  1357. X    }
  1358. X    return(p);
  1359. X}
  1360. X
  1361. Xflushmidi()
  1362. X{
  1363. X    while ( STATMIDI )
  1364. X        getmidi();
  1365. X}
  1366. X
  1367. X/* getmouse - get currect row and column of mouse */
  1368. Xgetmouse(amr,amc)
  1369. Xint *amr;
  1370. Xint *amc;
  1371. X{
  1372. X    *amr = -1;
  1373. X    *amc = -1;
  1374. X}
  1375. X
  1376. X/* statmouse - return mouse button state (0=nothing pressed,1=left,2=right) */
  1377. Xstatmouse()
  1378. X{
  1379. X    return(-1);
  1380. X}
  1381. X
  1382. X/* Return when either a console key or mouse button is pressed. */
  1383. Xmouseorkey()
  1384. X{
  1385. X    return(getconsole());
  1386. X}
  1387. X
  1388. X#ifdef C86
  1389. Xgetch()
  1390. X{
  1391. X    struct regval sreg, rreg;
  1392. X    sreg.ax = 0x0000;
  1393. X    sysint(0x16, &sreg, &rreg);
  1394. X    return(rreg.ax & 0x7f);
  1395. X}
  1396. X#endif
  1397. X
  1398. Xwindinit()
  1399. X{
  1400. X}
  1401. X
  1402. Xwindgoto(r,c)
  1403. Xint r,c;
  1404. X{
  1405. X#ifdef C86
  1406. X    struct regval sreg, rreg;
  1407. X    sreg.ax = 0x200;
  1408. X    sreg.bx = 0;
  1409. X    sreg.dx = (r<<8) | c ;
  1410. X    sysint(0x10, &sreg, &rreg);
  1411. X#endif
  1412. X#ifdef TURBOC
  1413. X    gotoxy(1+c,1+r);
  1414. X#endif
  1415. X}
  1416. X
  1417. Xwinderaserow(r)
  1418. X{
  1419. X#ifdef C86
  1420. X    struct regval sreg, rreg;
  1421. X    sreg.ax = 0x0600;
  1422. X    sreg.bx = 0;
  1423. X    sreg.cx = (r<<8);    /* urow, lcol */
  1424. X    sreg.dx = (r<<8) | 79;
  1425. X    sysint(0x10, &sreg, &rreg);
  1426. X#endif
  1427. X#ifdef TURBOC
  1428. X    gotoxy(1,r+1);
  1429. X    clreol();
  1430. X#endif
  1431. X}
  1432. X
  1433. Xwindexit()
  1434. X{
  1435. X    /* windgoto(23,0);
  1436. X    windrefresh();
  1437. X    nocbreak();
  1438. X    nl();
  1439. X    echo();
  1440. X    endwin(); */
  1441. X}
  1442. X
  1443. Xwindclear()
  1444. X{
  1445. X#ifdef C86
  1446. X    struct regval sreg, rreg;
  1447. X    sreg.ax = 0x0600;
  1448. X    sreg.bx = 0;
  1449. X    sreg.cx = 0;    /* urow, lcol */
  1450. X    sreg.dx = (24<<8) | 79;
  1451. X    sysint(0x10, &sreg, &rreg);
  1452. X#endif
  1453. X#ifdef TURBOC
  1454. X    clrscr();
  1455. X#endif
  1456. X}
  1457. X
  1458. X/* windgets - get a line of input from the console, handling backspaces */
  1459. Xwindgets(s)
  1460. Xchar *s;
  1461. X{
  1462. X    char *origs = s;
  1463. X    int c;
  1464. X
  1465. X    while ( (c=getconsole()) != '\n' && c!='\r' && c!= EOF ) {
  1466. X        if ( c == '\b' ) {
  1467. X            if ( s > origs ) {
  1468. X                windstr("\b \b");
  1469. X                s--;
  1470. X            }
  1471. X        }
  1472. X        else {
  1473. X            windputc(c);
  1474. X            *s++ = c;
  1475. X        }
  1476. X        windrefresh();
  1477. X    }
  1478. X    *s = '\0';
  1479. X}
  1480. X
  1481. Xwindstr(s)
  1482. Xchar *s;
  1483. X{
  1484. X    int c;
  1485. X
  1486. X    while ( (c=(*s++)) != '\0' )
  1487. X        windputc(c);
  1488. X}
  1489. X
  1490. Xwindputc(c)
  1491. Xint c;
  1492. X{
  1493. X    putchar(c);
  1494. X}
  1495. X
  1496. Xwindrefresh()
  1497. X{
  1498. X}
  1499. X
  1500. Xbeep()
  1501. X{
  1502. X    putchar('\007');
  1503. X}
  1504. X
  1505. Xwindhigh()
  1506. X{
  1507. X}
  1508. X
  1509. Xwindnorm()
  1510. X{
  1511. X}
  1512. X
  1513. X/****************
  1514. X * openls(), nextls(), and closels() are used to scan the current directory.
  1515. X ***************/
  1516. X
  1517. Xint first = 1;
  1518. Xopenls()
  1519. X{
  1520. X    first = 1;
  1521. X}
  1522. Xchar *
  1523. Xnextls()
  1524. X{
  1525. X    static struct ffblk ffblk;
  1526. X    int n;
  1527. X
  1528. X    if ( first ) {
  1529. X        n = findfirst("*.*",&ffblk,0);
  1530. X        first = 0;
  1531. X    }
  1532. X    else
  1533. X        n = findnext(&ffblk);
  1534. X
  1535. X    if ( n == 0 )
  1536. X        return(ffblk.ff_name);
  1537. X    else
  1538. X        return((char *)NULL);
  1539. X}
  1540. Xclosels()
  1541. X{
  1542. X}
  1543. X
  1544. X#ifdef OLDSTUFF
  1545. X/*
  1546. X * The following MPU code has been provided by Steve Frysinger (moss!spf).
  1547. X */
  1548. X
  1549. X#define    STATUS_PORT    0x0331
  1550. X#define    COMMAND_PORT    0x0331
  1551. X#define    DATA_PORT    0x0330
  1552. X#define    DATA_READY_MASK    0x40
  1553. X#define    DATA_AVAIL_MASK    0x80
  1554. X
  1555. Xint send_command_4001(val)    /* Patterned after Voyetra's reset_4001() */
  1556. Xunsigned val;
  1557. X{
  1558. X    unsigned x = 0;
  1559. X    int flag;
  1560. X    int ack_count,time_count;
  1561. X    int retval=1; /* Assume success */
  1562. X    inportb(DATA_PORT);
  1563. X    for (time_count=5000,flag=1;time_count&&flag;time_count--)
  1564. X    {
  1565. X        if (!(inportb(STATUS_PORT)&DATA_READY_MASK)) flag=0;
  1566. X    }
  1567. X    if (flag)
  1568. X    {
  1569. X        fprintf(stderr,"Command timeout waiting for port!\n");
  1570. X        retval = -1;
  1571. X    }
  1572. X    else
  1573. X    {
  1574. X        outportb(COMMAND_PORT,val);
  1575. X        for (time_count=10000,ack_count=5,flag=0;!flag;)
  1576. X        {
  1577. X            if ((inportb(STATUS_PORT)&DATA_AVAIL_MASK))
  1578. X            {
  1579. X                time_count--;
  1580. X                if (!time_count)
  1581. X                {
  1582. X                    flag++;
  1583. X                    fprintf(stderr,"Command timeout waiting for ACK.\n");
  1584. X                    retval = -1;
  1585. X                }
  1586. X            }
  1587. X            else
  1588. X            {
  1589. X                x = (unsigned)inportb(DATA_PORT);
  1590. X                if (x == 0xfe)
  1591. X                {
  1592. X                    flag++;
  1593. X                    fprintf(stderr,"Got command acknowledgement\n");
  1594. X                }
  1595. X                else
  1596. X                {
  1597. X                    ack_count--;
  1598. X                    if (!ack_count)
  1599. X                    {
  1600. X                        printf("Too many data bytes without ACK\n");
  1601. X                        retval = -1;
  1602. X                    }
  1603. X                }
  1604. X            }
  1605. X        }
  1606. X    }
  1607. X    return(retval);
  1608. X} /* send_command_4001 */
  1609. X#endif
  1610. X
  1611. X/*
  1612. X * Acknowledgements to John Helton for additions to support ATT PC6300 w/
  1613. X * MPU401 and OP4000 MIDI Interface Controllers.
  1614. X * PC6300 support uses Borland TurboC 'C' compiler, large model
  1615. X *
  1616. X */
  1617. X#define QUIT 1
  1618. X#define NOQUIT 0
  1619. X
  1620. Xvoid interrupt (*oldint0)();
  1621. Xvoid interrupt (*oldint2)();
  1622. Xvoid interrupt (*oldint1b)();
  1623. Xvoid interrupt (*oldint23)();
  1624. Xvoid interrupt (*oldint24)();
  1625. Xvoid interrupt ctr_brk_handler();
  1626. Xvoid interrupt fatal_err_hndlr();
  1627. X
  1628. Xvoid interrupt far tick_isr();
  1629. Xvoid interrupt far midi_isr();
  1630. Xextern unsigned long hzcount;
  1631. Xextern char midi_buffer[];
  1632. Xextern int wrt_index, rd_index;
  1633. X
  1634. Xextern unsigned _stklen;    /* Turbo C specific */ 
  1635. X
  1636. Xint Nextpcchar = EOF;
  1637. Xint Fakemidi = 0;
  1638. Xint (*Intfunc)() = NULL;
  1639. X
  1640. Xhello()
  1641. X{
  1642. X    _stklen = 50000;
  1643. X    hzcount = 0L;            /* init timer & buffer globals */
  1644. X    wrt_index = rd_index = 0;
  1645. X    if (!setup_MIC())            /* Set up the Midi Interface Ctrl */
  1646. X    {
  1647. X    if ( fisatty(stdout) )
  1648. X        printf("Can't initialize midi interface\n");
  1649. X    Fakemidi = 1;
  1650. X    reset_ints(NOQUIT);        /* restore interrupts to a suitable
  1651. X                       condition to keep running without
  1652. X                       the Midi Interface (for testing) */
  1653. X    return;
  1654. X    }
  1655. X    send_msg(UART, COMMAND_MSG);    /* run the MIC in dumb mode */
  1656. X    return;
  1657. X}
  1658. X
  1659. Xrtend()
  1660. X{
  1661. X    reset_MIC();
  1662. X}
  1663. X
  1664. Xbye()
  1665. X{
  1666. X    system_exit();
  1667. X}
  1668. X
  1669. Xflushconsole()
  1670. X{ return; }
  1671. X
  1672. Xgetconsole()
  1673. X{
  1674. X    int c;
  1675. X
  1676. X    if ( Nextpcchar != EOF ) {
  1677. X        c = Nextpcchar;
  1678. X        Nextpcchar = EOF;
  1679. X    }
  1680. X    else {
  1681. X        c = getch();
  1682. X    }
  1683. X    return(c);
  1684. X}
  1685. X
  1686. Xputconsole(c)
  1687. X{
  1688. X    putch(c);
  1689. X}
  1690. X
  1691. X/* getmidi reads data out of the circular midi buffer */
  1692. Xgetmidi()
  1693. X{
  1694. X    static char mbuff[1];
  1695. X    unsigned char *p;
  1696. X
  1697. X    while ( wrt_index == rd_index)
  1698. X        ;
  1699. X    rd_index++;
  1700. X    if (rd_index > 511) rd_index = 0;
  1701. X    mbuff[0] = midi_buffer[rd_index];
  1702. X    return (mbuff[0] & 0xff);
  1703. X}
  1704. X
  1705. Xsendmidi(val)
  1706. Xint val;
  1707. X{
  1708. X    unsigned char p[1];
  1709. X    p[0] = val;
  1710. X    putnmidi(1,p);
  1711. X}
  1712. X
  1713. Xputnmidi(n,p)
  1714. Xchar *p;
  1715. X{
  1716. X    while ( n-- > 0 ) {
  1717. X        int c = (*p++) & 0xff;
  1718. X        if ( Fakemidi )
  1719. X        printf("putmidi(d=%d x=%x o=%o)\n",c,c,c);
  1720. X        else
  1721. X        write_data_MPU(c);
  1722. X    }
  1723. X}
  1724. X
  1725. Xresetclock()
  1726. X{
  1727. X    hzcount = 0L;
  1728. X}
  1729. X
  1730. Xlong
  1731. Xmilliclock()
  1732. X{
  1733. X    return (hzcount*5L);
  1734. X}
  1735. X
  1736. X/* filetime - Return the modification time of a file in seconds. */
  1737. Xlong
  1738. Xfiletime(fn)
  1739. Xchar *fn;    /* file name */
  1740. X{
  1741. X    struct stat s;
  1742. X
  1743. X    if ( stat(fn,&s) == -1 )
  1744. X        return(-1);
  1745. X    return(s.st_mtime);
  1746. X}
  1747. X
  1748. X/* currtime - Return current time in seconds (consistent with filetime()) */
  1749. Xlong
  1750. Xcurrtime()
  1751. X{
  1752. X    long time();
  1753. X    return ( time((long *)0) );
  1754. X}
  1755. X
  1756. Xfisatty(f)
  1757. XFILE* f;
  1758. X{
  1759. X    return(isatty(fileno(f)));
  1760. X}
  1761. X
  1762. X/*
  1763. X * send_msg(COM, TYPE, PTR, LENGTH)
  1764. X * will send command to Midi Interface Controller (MIC) Command port, 
  1765. X * then either return, wait for data or send data
  1766. X */
  1767. X
  1768. Xsend_msg(com, type, ptr, length)
  1769. Xint com, type, length;
  1770. Xchar *ptr;
  1771. X{
  1772. X    int acked;
  1773. X    int x;
  1774. X
  1775. X    while ( NOT_READY_FOR_DATA_MIC());
  1776. X    disable_ints();
  1777. X    COMMAND_OUT_MIC((char) com);    /* send the command to the MIC */
  1778. X    for(acked=0; !acked; ) {        /* wait until our command is acked */
  1779. X        x = read_MPU();            /* get a byte back from the MIC */
  1780. X        if (x == ACK) acked++;        /* done if ACK received */
  1781. X        else write_rcv_buff(x);        /* deal with this input stream first */
  1782. X    }
  1783. X    if (type == WRITE_MSG)        /* if write request... */
  1784. X        for (; length; ptr++, length--) write_data_MPU(*ptr);
  1785. X                    /* write all the bytes to the MIC */
  1786. X    enable_ints();            /* ints restored to where they were
  1787. X                       before we shut them off */
  1788. X}
  1789. X
  1790. X
  1791. X/* WRITE_RCV_BUFF(INPUT)
  1792. X * part of the command handshake sequence.  Input read from the
  1793. X * midi data port is saved in wraparound FIFO
  1794. X*/
  1795. X
  1796. Xwrite_rcv_buff(val)
  1797. Xint val;
  1798. X{
  1799. X    wrt_index++;
  1800. X    if (wrt_index > 511) wrt_index = 0;
  1801. X    midi_buffer[wrt_index] = (char) val;
  1802. X}
  1803. X
  1804. X/*
  1805. X * SETUP_MIC()
  1806. X * resets MIC, sets up int vectors and enables int system
  1807. X * Returns - true if MIC set ok
  1808. X */
  1809. X
  1810. Xstatic setup_MIC()
  1811. X{
  1812. X    int retval;
  1813. X
  1814. X    set_ints();            /* set the new interrupt vectors */
  1815. X    init_enable_MPU();         /* turn on interrupt system for first time */
  1816. X    retval = reset_MIC();        /* try to reset MIC */
  1817. X    if (!retval) retval = reset_MIC(); /* if no good, try again */
  1818. X    init_enable_TIMER();    /* turn on timer interrupt if reset ok*/
  1819. X    return(retval);
  1820. X}
  1821. X
  1822. X/*
  1823. X * RESET_MIC()
  1824. X * attempts to do a low level software reset on the MIC
  1825. X * returns - true if success
  1826. X */
  1827. X
  1828. Xreset_MIC()
  1829. X{
  1830. X    unsigned x = 0;
  1831. X    int flag;
  1832. X    int ack_count, time_count;
  1833. X    int retval=1;        /* assume success */
  1834. X    
  1835. X    disable_ints();        /* disable interrupts */
  1836. X    READ_DATA_MIC();        /* Clear out any data in receiver */
  1837. X    /* Here we will loop until ready for data, or we give up     */
  1838. X    for (time_count=5000, flag=1; time_count && flag; time_count--) {
  1839. X    /* if MIC ready for data, we can quit loop */
  1840. X        if (!(NOT_READY_FOR_DATA_MIC())) flag=0;
  1841. X    }
  1842. X    /* if timed out before we got ready for data, return flag couldn't reset */
  1843. X    if (flag){    
  1844. X    retval = 0;
  1845. X    }
  1846. X    else {
  1847. X        COMMAND_OUT_MIC(RESET); /* Send the reset command */
  1848. X    /* loop here till time out, or ack recvd */
  1849. X        for (time_count=10000, ack_count=5, flag=0; !flag;) {
  1850. X        if ((NOT_DATA_AVAILABLE_MIC())) { /* if no data from MIC */
  1851. X            time_count--;        /* count one more wait */
  1852. X            if (!time_count) {
  1853. XBAD_RESET:
  1854. X            flag++;        /* if time out, note it */
  1855. X            retval=0;        /* and note failure */
  1856. X        }
  1857. X        }
  1858. X        else {        /* If there is data coming back form MIC */
  1859. X            x = (unsigned) READ_DATA_MIC(); /* ...read it */
  1860. X            if (x == ACK) { /* If data is the ACK message */
  1861. X            flag++;        /* note we are done, and no failure */
  1862. X        }
  1863. X            else {        /* if data back from MIC wasn't ack */
  1864. X            ack_count--;/* note that we got something that isn't ack */
  1865. X            if (!ack_count) goto BAD_RESET;
  1866. X                /* If we get too many data bytes back from
  1867. X                   MIC with no ack, give up */
  1868. X        }
  1869. X        }
  1870. X    }
  1871. X    }
  1872. X    enable_ints();             /* turn ints back on */
  1873. X    return(retval);
  1874. X}
  1875. X
  1876. X/*
  1877. X * SYSTEM_EXIT()
  1878. X * called to leave program.  resets ints and exits
  1879. X */
  1880. Xsystem_exit()
  1881. X{
  1882. X    reset_MIC();
  1883. X    disable_ints();
  1884. X    reset_ints(QUIT);    /* put all the int vectors back where they were */
  1885. X    reset_TIMER();
  1886. X    enable_ints();
  1887. X    windexit(0);
  1888. X    exit();
  1889. X}
  1890. X
  1891. X/*
  1892. X * hi level interrupt routines
  1893. X */
  1894. X
  1895. Xvoid interrupt
  1896. Xctr_brk_handler()
  1897. X{
  1898. X    if ( Intfunc != NULL )
  1899. X    (*Intfunc)();
  1900. X    printf("interrupts reset; BYE!\n");
  1901. X    system_exit();
  1902. X}
  1903. X
  1904. Xvoid interrupt
  1905. Xfatal_err_hndlr()
  1906. X{
  1907. X    fatal_dos_handler();
  1908. X}
  1909. X
  1910. Xfatal_dos_handler()    /* called by fatal error handler ISR */
  1911. X{
  1912. X    printf("got fatal error; BYE!\n");
  1913. X    system_exit();
  1914. X}
  1915. X
  1916. Xset_ints()
  1917. X{
  1918. X    oldint0 = getvect(0x08);    /* timer interrupt on irq0 */
  1919. X    setvect(0x08, tick_isr);
  1920. X    oldint2 = getvect(0x0a);    /* midi interrupt on irq2 */
  1921. X    setvect(0x0a, midi_isr);
  1922. X    oldint1b = getvect(0x1b);    /* the rest of these are dos & bios ints */
  1923. X    setvect(0x1b, ctr_brk_handler);
  1924. X    oldint23 = getvect(0x23);
  1925. X    setvect(0x23, ctr_brk_handler);
  1926. X    oldint24 = getvect(0x24);
  1927. X    setvect(0x24, fatal_err_hndlr);
  1928. X}
  1929. X
  1930. Xreset_ints(reset_type)
  1931. X{
  1932. X    if (reset_type == QUIT) {
  1933. X        setvect(0x08, oldint0);
  1934. X        setvect(0x1b, oldint1b);
  1935. X        setvect(0x23, oldint23);
  1936. X        setvect(0x24, oldint24);
  1937. X    }
  1938. X    setvect(0x0a, oldint2);    /* only need to reset one hardware interrupt
  1939. X                   if we're not going to quit */
  1940. X}
  1941. X
  1942. Xsignal(type,func)
  1943. Xint (*func)();
  1944. X{
  1945. X    if ( type == SIGINT ) {
  1946. X        if ( func == SIG_IGN )
  1947. X            Intfunc = NULL;
  1948. X        else
  1949. X            Intfunc = func;
  1950. X    }
  1951. X}
  1952. END_OF_FILE
  1953. if test 11518 -ne `wc -c <'pc-mach.c'`; then
  1954.     echo shar: \"'pc-mach.c'\" unpacked with wrong size!
  1955. fi
  1956. # end of 'pc-mach.c'
  1957. fi
  1958. echo shar: End of archive 6 \(of 15\).
  1959. cp /dev/null ark6isdone
  1960. MISSING=""
  1961. for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 ; do
  1962.     if test ! -f ark${I}isdone ; then
  1963.     MISSING="${MISSING} ${I}"
  1964.     fi
  1965. done
  1966. if test "${MISSING}" = "" ; then
  1967.     echo You have unpacked all 15 archives.
  1968.     rm -f ark[1-9]isdone ark[1-9][0-9]isdone
  1969. else
  1970.     echo You still need to unpack the following archives:
  1971.     echo "        " ${MISSING}
  1972. fi
  1973. ##  End of shell archive.
  1974. exit 0
  1975.  
  1976.